﻿using CertApply.Component;
using MessagePack;
using Microsoft.Extensions.DependencyInjection;
using PluginForDNSRecord;
using Service;
using Service.Model;
using Service.Utity;
using System.Security.Cryptography;
using System.Text.RegularExpressions;

namespace CertApply
{
    public partial class frmAddAutomatic : Form
    {
        private List<IDNSRecordEditor> dNSRecordEditors;
        public List<CertHandOutConfig> CertHandOutConfigs { get; set; } = new List<CertHandOutConfig>();
        private DnsEditorConfig dnsEditorConfig;
        private RSA _rsa;
        public frmAddAutomatic()
        {
            dNSRecordEditors = new List<IDNSRecordEditor>();
            dnsEditorConfig = new DnsEditorConfig();
            var rsaInfo = RSAStore.GetRSA();
            if (rsaInfo.message.Length > 0)
            {
                MessageBox.Show(rsaInfo.message);
                Environment.Exit(0);
            }
            _rsa = rsaInfo.Result;
            InitializeComponent();
            loadcbo_DnsRecordEditorPlugin();
        }

        public frmAddAutomatic(string filePath)
        {
            var rsaInfo = RSAStore.GetRSA();
            if (rsaInfo.message.Length > 0)
            {
                MessageBox.Show(rsaInfo.message);
                Environment.Exit(0);
            }
            _rsa = rsaInfo.Result;
            var automaticConfig = ConfigHelper.GetConfig(_rsa, filePath);
            InitializeComponent();
            cbo_DnsRecordEditorPlugin.SelectedIndexChanged -= cbo_DnsRecordEditorPlugin_SelectedIndexChanged;
            loadcbo_DnsRecordEditorPlugin();
            List<FormItem> formItems = new List<FormItem>();
            foreach (var item in automaticConfig.DnsEditorConfig.ConfigItems)
            {
                formItems.Add(new FormItem()
                {
                    Key = item.Key,
                    DisplayName = item.DisplayName,
                    IsSecret = item.IsSecret,
                    Value = automaticConfig.DnsEditorConfig.Config[item.Key]
                });
            }
            flowLayoutPanelDnsRecordConfig.Controls.Clear();
            flowLayoutPanelDnsRecordConfig.Controls.AddRange(formItems.ToArray());
            CertHandOutConfigs = automaticConfig.CertHandOutConfig;
            dnsEditorConfig = automaticConfig.DnsEditorConfig;
            txtDomain.Text = automaticConfig.Domain;
            txtEmail.Text = automaticConfig.Email;
            cbo_DnsRecordEditorPlugin.SelectedIndexChanged += cbo_DnsRecordEditorPlugin_SelectedIndexChanged;
            bindDataToControl();
        }

        private void loadcbo_DnsRecordEditorPlugin()
        {
            dNSRecordEditors = PluginFactory.CreateDNSRecordEditorInstance();
            cbo_DnsRecordEditorPlugin.DisplayMember = "Identity";
            cbo_DnsRecordEditorPlugin.ValueMember = "Identity";
            cbo_DnsRecordEditorPlugin.DataSource = dNSRecordEditors;
        }
        private void frmAddAutomatic_Load(object sender, EventArgs e)
        {

        }
        private void cbo_DnsRecordEditorPlugin_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbo_DnsRecordEditorPlugin.SelectedValue != null)
            {
                var selectedItem = dNSRecordEditors.FirstOrDefault(s => s.Identity == cbo_DnsRecordEditorPlugin.SelectedValue.ToString());
                List<FormItem> formItems = new List<FormItem>();
                foreach (var item in selectedItem.ConfigKey)
                {
                    formItems.Add(new FormItem()
                    {
                        Key = item.Key,
                        DisplayName = item.DisplayName,
                        IsSecret = item.IsSecret
                    });
                }
                flowLayoutPanelDnsRecordConfig.Controls.Clear();
                flowLayoutPanelDnsRecordConfig.Controls.AddRange(formItems.ToArray());
            }
        }
        private void btn_add_Click(object sender, EventArgs e)
        {
            frmEditCertDistribute frmEditCertDistribute = new frmEditCertDistribute();
            var dialogResult = frmEditCertDistribute.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                var item = CertHandOutConfigs.FirstOrDefault(s => s.Name == frmEditCertDistribute.certHandOutConfig.Name);
                if (item != null)
                {
                    item = frmEditCertDistribute.certHandOutConfig;
                }
                else
                {
                    CertHandOutConfigs.Add(frmEditCertDistribute.certHandOutConfig);
                }
                bindDataToControl();
            }
        }
        private void bindDataToControl()
        {
            flowLayoutPanelComputerServerOprationConfig.Controls.Clear();
            List<Button> buttonList = new List<Button>();
            foreach (var item in CertHandOutConfigs)
            {
                var btn = new Button()
                {
                    Tag = item,
                    Text = item.Name,
                    AutoSize = true,
                };
                btn.Click += CertHandOutConfig_Click;
                buttonList.Add(btn);
            }
            flowLayoutPanelComputerServerOprationConfig.Controls.AddRange(buttonList.ToArray());
        }
        private void CertHandOutConfig_Click(object sender, EventArgs e)
        {
            var entity = ((sender as Button).Tag) as CertHandOutConfig;

            frmEditCertDistribute frmEditCertDistribute = new frmEditCertDistribute(entity);
            var dialogResult = frmEditCertDistribute.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                var item = CertHandOutConfigs.FirstOrDefault(s => s.Name == frmEditCertDistribute.certHandOutConfig.Name);
                if (item != null)
                {
                    CertHandOutConfigs.Remove(item);
                    CertHandOutConfigs.Add(frmEditCertDistribute.certHandOutConfig);
                }
                else
                {
                    CertHandOutConfigs.Add(frmEditCertDistribute.certHandOutConfig);
                }
                bindDataToControl();
            }
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            var dnsRecordEditorPluginIdentity = cbo_DnsRecordEditorPlugin.SelectedValue.ToString();
            var email = txtEmail.Text;
            var domain= txtDomain.Text;
            Task.Factory.StartNew(() =>
            {
                btnSave.Invoke(() =>
                {
                    labMsg.Text = "正在执行,请稍等";
                    btnSave.Enabled = false;
                });
                string regEmailStr = @"[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?";
                Regex regEmail = new Regex(regEmailStr, RegexOptions.IgnoreCase);
                if (!regEmail.Match(email).Success)
                {
                    btnSave.Invoke(() =>
                    {
                        labMsg.Text = "邮箱输入错误,请输入一个可用的邮箱";
                        btnSave.Enabled = true;
                    });
                    return;
                }
                if (string.IsNullOrEmpty(domain))
                {
                    btnSave.Invoke(() =>
                    {
                        labMsg.Text = "请输入域名";
                        btnSave.Enabled = true;
                    });
                    return;
                }
                else
                {
                    var sd = DomainHelper.GetSubDomain(domain);
                    if (sd.Contains("*") && sd.Length > 1)
                    {
                        btnSave.Invoke(() =>
                        {
                            labMsg.Text = "域名格式错误，如果是通配符域名，请输入 *.domain.com, 非通配符域名，请输入xxx.domain.com  其中domain.com为申请/购买的域名";
                            btnSave.Enabled = true;
                        });
                        return;
                    }
                }
                //构建最终完成的对象:
                var selectedPlugin = dNSRecordEditors.FirstOrDefault(s => s.Identity == dnsRecordEditorPluginIdentity);
                Dictionary<string, string> dnsEditorConfig = new Dictionary<string, string>();
                foreach (FormItem item in flowLayoutPanelDnsRecordConfig.Controls)
                {
                    dnsEditorConfig.Add(item.Key, item.Value);
                }
                var dnsEditorConfigItems = new List<Service.Model.ConfigItem>();
                foreach (var item in selectedPlugin.ConfigKey)
                {
                    dnsEditorConfigItems.Add(new Service.Model.ConfigItem()
                    {
                        DisplayName = item.Key,
                        IsSecret = item.IsSecret,
                        Key = item.Key,
                    });
                }
                AutomaticConfig automaticConfig = new AutomaticConfig
                {
                    DnsEditorConfig = new DnsEditorConfig()
                    {
                        PluginIdentity = selectedPlugin.Identity,
                        ConfigItems = dnsEditorConfigItems,
                        Config = dnsEditorConfig
                    },
                    CertHandOutConfig = this.CertHandOutConfigs,
                    Email = txtEmail.Text.Trim(),
                    Domain = txtDomain.Text.Trim()
                };
                //文件名称
                var subDomain = DomainHelper.GetSubDomain(txtDomain.Text);
                var rootDomain = DomainHelper.GetRootDomain(txtDomain.Text);
                string fileName = $"{txtDomain.Text.Trim()}.domain";
                if (subDomain == "*")
                {
                    fileName = $"{rootDomain}_All.domain";
                }
                string filePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "AutomaticDomains", fileName);
                automaticConfig.SaveConfig(_rsa, filePath);
                btnSave.Invoke(() =>
                {
                    btnSave.Enabled = true;
                    DialogResult = DialogResult.OK;
                });
            });
        }
    }
}
